package com.fc.mall.service.impl;

import com.fc.mall.dao.OmsOrderDao;
import com.fc.mall.dao.UmsMemberAccountChangeHistoryDao;
import com.fc.mall.dao.UmsMemberDao;
import com.fc.mall.dto.*;
import com.fc.mall.dto.*;
import com.fc.mall.exception.ServiceException;
import com.fc.mall.mapper.*;
import com.fc.mall.model.*;
import com.fc.mall.mapper.*;
import com.fc.mall.model.UmsMemberAccountChangeHistory;
import com.fc.mall.service.UmsMemberService;
import com.fc.mall.util.Constants;
import com.fc.mall.util.DateTimeHelper;
import com.fc.mall.util.Utils;
import com.fc.mall.model.*;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by Sunny on 2019/5/28.
 */
@Service
public class UmsMemberServiceImpl implements UmsMemberService {

    @Autowired
    private UmsMemberMapper umsMemberMapper;

    @Autowired
    private UmsMemberDao umsMemberDao;

    @Autowired
    private UmsMemberInviteHistoryMapper memberInviteHistoryMapper;

    @Autowired
    private UmsMemberUpgradeMapper memberUpgradeMapper;

    @Autowired
    private UmsMemberSignMapper memberSignMapper;

    @Autowired
    private UmsMemberBankMapper memberBankMapper;

    @Autowired
    private OmsOrderMapper orderMapper;

    @Autowired
    private UmsMemberAccountChangeHistoryDao accountChangeHistoryDao;

    @Autowired
    private OmsOrderDao orderDao;


    @Override
    public List<UmsMember> getList(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        UmsMemberExample example = new UmsMemberExample();
        List<UmsMember> umsMemberList = umsMemberMapper.selectByExample(example);
        return umsMemberList;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void upgradeMemberLevel(UmsMember umsMember) {
        if (umsMember.getLevelType().intValue() == Constants.MemberLevelType.Partner.getValue()) {
            // TODO: HardCode  合伙人是的levelId默认是 5
            umsMember.setMemberLevelId(5L);
        } else if (umsMember.getLevelType().intValue() == Constants.MemberLevelType.Member.getValue()) {
            // TODO: HardCode  会员是的levelId默认是 5
            umsMember.setMemberLevelId(1L);
        }
        //传parentMemberId时自动设置parentPath
        if (!StringUtils.isEmpty(umsMember.getParentMemberId())){
            UmsMember parentMember=umsMemberMapper.selectByPrimaryKey(umsMember.getParentMemberId());
            if (!StringUtils.isEmpty(parentMember.getParentPath())){
                umsMember.setParentPath(parentMember.getParentPath()+","+umsMember.getParentMemberId());
            }else{
                umsMember.setParentPath(","+umsMember.getParentMemberId());
            }
        }
        umsMemberMapper.updateByPrimaryKeySelective(umsMember);

        UmsMemberUpgradeExample upgradeExample = new UmsMemberUpgradeExample();
        upgradeExample.createCriteria().andMemberIdEqualTo(umsMember.getId());
        List<UmsMemberUpgrade> memberUpgradeList = memberUpgradeMapper.selectByExample(upgradeExample);

        if (null != memberUpgradeList && !memberUpgradeList.isEmpty()) {
            UmsMemberUpgrade memberUpgrade = new UmsMemberUpgrade();
            memberUpgrade.setId(memberUpgradeList.get(0).getId());
            if (null != umsMember.getMemberLevelId()) {
                memberUpgrade.setCurrentLevelId(umsMember.getMemberLevelId());
            }
            // 2 为手动升级
            memberUpgrade.setUpgradeType(UmsMemberUpgrade.UpgradeType.MANUAL.getValue());
            memberUpgrade.setExpiredType(umsMember.getExpireType());
            memberUpgrade.setExpiredDate(getExpireDate(umsMember.getExpireType()));
            memberUpgradeMapper.updateByPrimaryKeySelective(memberUpgrade);
        }


    }

    @Override
    public int delMember(Long memberId) {

        checkDeleteMember(memberId);
        //删除签到
        UmsMemberSignExample signExample = new UmsMemberSignExample();
        signExample.createCriteria().andMemberIdEqualTo(memberId);
        memberSignMapper.deleteByExample(signExample);
        // 删除邀请
        UmsMemberInviteHistoryExample example = new UmsMemberInviteHistoryExample();
        example.createCriteria().andMemberIdEqualTo(memberId);
        memberInviteHistoryMapper.deleteByExample(example);

        return umsMemberMapper.deleteByPrimaryKey(memberId);
    }

    @Override
    public List<UmsMemberFull> getFullMemberList(UmsMemberQueryParam param, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        param.setNickname(Utils.urlEncoderTransfer(param.getNickname()));

        List<UmsMemberFull> memberFullList = umsMemberDao.queryList(param, pageNum, pageSize);
        formatMemberList(memberFullList);
        return memberFullList;
    }

    @Override
    public List<UmsMemberFull> getMemberRelation(Long memberId) {
        UmsMember member = umsMemberMapper.selectByPrimaryKey(memberId);
        if (StringUtils.isEmpty(member.getParentPath())) {
            return new ArrayList<>();
        }

        List<UmsMemberFull> memberFullList = new ArrayList<>();

        //先放入该memberId的信息
        UmsMemberQueryParam memberQueryParam = new UmsMemberQueryParam();
        memberQueryParam.setMemberId(memberId);
        memberFullList.add(umsMemberDao.queryList(memberQueryParam, 1, 5).get(0));

        //查询parentPath中的会员信息
        String[] ids = member.getParentPath().split(",");
        for (int i = ids.length - 1; i >= 0; i--){
            if (!StringUtils.isEmpty(ids[i])){
                memberQueryParam = new UmsMemberQueryParam();
                memberQueryParam.setMemberId(Long.valueOf(ids[i]));
                memberFullList.add(umsMemberDao.queryList(memberQueryParam, 1, 5).get(0));
            }
        }
        formatMemberList(memberFullList);
        return memberFullList;
    }

    @Override
    public List<UmsMemberCommission> getMemberCommissionList(UmsMemberCommissionParam umsMemberCommissionParam, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<UmsMemberCommission> umsMemberCommissions = umsMemberDao.queryMemberCommission(umsMemberCommissionParam);
        umsMemberCommissions.stream().forEach(v->{
            if(null != v)
            {
                v.setNickname(Utils.urlDecoderTransfer(v.getNickname()));
            }
        });

        return umsMemberCommissions;
    }

    @Override
    public UmsMemberBank getMemberBank(Long memberId) {
        UmsMemberBankExample example = new UmsMemberBankExample();
        example.createCriteria().andMemberIdEqualTo(memberId);
        List<UmsMemberBank> umsMemberBankList = memberBankMapper.selectByExample(example);
        if (null == umsMemberBankList || umsMemberBankList.isEmpty()) {
            return new UmsMemberBank();
        }

        return umsMemberBankList.get(0);
    }

    @Override
    public UmsMemberIncomeStaticInfo getMemberIncomeStatic(Long memberId) {

        final UmsMemberIncomeStaticInfo incomeStaticInfo = new UmsMemberIncomeStaticInfo();
        // 本月收益，与 预估 （到账收益）
        List<UmsMemberAccountChangeHistory> currentMonthAccountCHList = accountChangeHistoryDao.getAccountHistoryByFilterType(memberId,3);
        currentMonthAccountCHList.stream().filter(v->v.getType().intValue() == 1).forEach(v -> {
            if(v.getAccountType().intValue() == 1)
            {
                int incomeAmount = incomeStaticInfo.getCurrentMonthIncomeAmount() + v.getAmount().intValue();
                incomeStaticInfo.setCurrentMonthIncomeAmount(incomeAmount);
            }
            // 未方法的status 值为 1
            if(v.getAccountType().intValue() == 2 && v.getStatus().intValue() == 1)
            {
                int willIncomeAmount = incomeStaticInfo.getCurrentMonthWillIncomeAmount() + v.getAmount().intValue();
                incomeStaticInfo.setCurrentMonthWillIncomeAmount(willIncomeAmount);
            }
        });

        // 上月收益与预估
        List<UmsMemberAccountChangeHistory> preMonthAccountCHList = accountChangeHistoryDao.getAccountHistoryByFilterType(memberId,4);
        preMonthAccountCHList.stream().filter(v->v.getType().intValue() == 1).forEach(v -> {
            if(v.getAccountType().intValue() == 1)
            {
                int incomeAmount = incomeStaticInfo.getPrvMonthIncomeAmount() + v.getAmount().intValue();
                incomeStaticInfo.setPrvMonthIncomeAmount(incomeAmount);
            }
            // 未方法的status 值为 1
            if(v.getAccountType().intValue() == 2 && v.getStatus().intValue() == 1)
            {
                int willIncomeAmount = incomeStaticInfo.getPrvMonthWillIncomeAmount() + v.getAmount().intValue();
                incomeStaticInfo.setPrvMonthWillIncomeAmount(willIncomeAmount);
            }
        });

        // 今日预计佣金
        List<UmsMemberAccountChangeHistory> todayMonthAccountCHList = accountChangeHistoryDao.getAccountHistoryByFilterType(memberId,1);
        todayMonthAccountCHList.stream().filter(v->v.getType().intValue() == 1 && v.getAccountType().intValue() == 2).forEach(v -> {
            int todayWillIncomeAmount  = incomeStaticInfo.getTodayWillIncomeAmount() + v.getAmount().intValue();
            incomeStaticInfo.setTodayWillIncomeAmount(todayWillIncomeAmount);
        });

        // 今日付款笔数
        int todayPaymentOrderCount  = orderDao.queryPaymentOrderCount(1, memberId);
        incomeStaticInfo.setTodayPaymentOrderCount(todayPaymentOrderCount);
        // 昨日付款笔数
        int yesterdayPaymentOrderCount  = orderDao.queryPaymentOrderCount(2, memberId);
        incomeStaticInfo.setYesterdayPaymentOrderCount(yesterdayPaymentOrderCount);
        // 昨日预计佣金
        List<UmsMemberAccountChangeHistory> yesterdayMonthAccountCHList = accountChangeHistoryDao.getAccountHistoryByFilterType(memberId,2);
        todayMonthAccountCHList.stream().filter(v->v.getType().intValue() == 1 && v.getAccountType().intValue() == 2).forEach(v -> {
            int yesterdayWillIncomeAmount  = incomeStaticInfo.getYesterdayWillIncomeAmount() + v.getAmount().intValue();
            incomeStaticInfo.setYesterdayWillIncomeAmount(yesterdayWillIncomeAmount);
        });
        return incomeStaticInfo;
    }

    /**
     * 通过memberId 获取该用户的基本信息、银行信息、账户信息、过期时间
     *
     * @param memberId
     * @return UmsMemberAccountAndBankDto
     */
    @Override
    public UmsMemberAccountAndBankDto getUmsMemberAndAccountAndBankInfo(Long memberId) {
        UmsMemberQueryParam param =new UmsMemberQueryParam();
        param.setMemberId(memberId);

        List<UmsMemberFull> list = getFullMemberList(param,1,10);

        UmsMemberBank memberBank = getMemberBank(memberId);

        UmsMemberFull memberFull=null;
        if (list !=null && !list.isEmpty())
        {
            memberFull=list.get(0);

            UmsMemberExample example = new UmsMemberExample();
            example.createCriteria().andParentMemberIdEqualTo(memberFull.getId());
            int count = umsMemberMapper.countByExample(example);
            memberFull.setHasFans(count > 0);

            //确认收货订单数量
            OmsOrderExample orderExample = new OmsOrderExample();
            orderExample.createCriteria().andMemberIdEqualTo(memberFull.getId()).andReceiveTimeIsNotNull();
            memberFull.setConfirmOrderNum(orderMapper.countByExample(orderExample));
        }
        UmsMemberUpgrade memberUpgrade = null;

        UmsMemberUpgradeExample example = new UmsMemberUpgradeExample();
        example.createCriteria().andMemberIdEqualTo(memberId);
        example.setOrderByClause("id desc");
        List<UmsMemberUpgrade> memberUpgradeList = memberUpgradeMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(memberUpgradeList))
        {
            memberUpgrade = memberUpgradeList.get(0);
        }
        return new UmsMemberAccountAndBankDto(memberFull, memberBank,memberUpgrade);
    }

    /**
     * 粉丝列表
     * @return
     */
    @Override
    public List<UmsMemberFull> queryFansList(Long memberId,UmsMemberFansQueryParam param){
        List<UmsMemberFull> allFansList = new ArrayList<>();
        param.setParentId(memberId);
        if (!StringUtils.isEmpty(param.getNickname())){
            param.setNickname(Utils.urlEncoderTransfer(param.getNickname()));
        }
        //查询所有粉丝
        if (StringUtils.isEmpty(param.getFilterType()) ||
                param.getFilterType().equals(UmsMemberFansFilterEnum.ALL_FILTER_FANS.getValue())){
            //获取一级粉丝
            param.setFilterType(UmsMemberFansFilterEnum.FIRST_FILTER_FANS.getValue());
            allFansList.addAll(umsMemberDao.queryFansList(param));

            //获取二级粉丝
            param.setFilterType(UmsMemberFansFilterEnum.SECOND_FILTER_FANS.getValue());
            allFansList.addAll(umsMemberDao.queryFansList(param));

            //获取三级粉丝
            param.setFilterType(UmsMemberFansFilterEnum.THIRD_FILTER_FANS.getValue());
            allFansList.addAll(umsMemberDao.queryFansList(param));
            //查询下级运营商时
        }else if (StringUtils.isEmpty(param.getFilterType()) ||
                param.getFilterType().equals(UmsMemberFansFilterEnum.OPERATOR_FILTER_FANS.getValue())){
            //粉丝等级为1
            param.setFilterType(UmsMemberFansFilterEnum.FIRST_FILTER_FANS.getValue());
            //合伙人会员等级类型为3
            int partner = 3;
            param.setLevelType(partner);
            allFansList = umsMemberDao.queryFansList(param);
        }else{
            allFansList = umsMemberDao.queryFansList(param);
        }
        allFansList.forEach(fans->{
            fans.setNickname(Utils.urlDecoderTransfer(fans.getNickname()));
            fans.setParentNickname(Utils.urlDecoderTransfer(fans.getParentNickname()));
        });
        return allFansList;
    }

    /**
     * 获取粉丝数量
     * @param memberId
     * @return
     */
    @Override
    public UmsMemberFansCount countFans(Long memberId) {
        UmsMemberExample example = new UmsMemberExample();
        UmsMemberFansCount fansCount = new UmsMemberFansCount();

        //查询一级粉丝数量
        example.createCriteria().andParentMemberIdEqualTo(memberId);
        fansCount.setFirstFansCount(umsMemberMapper.countByExample(example));

        //查询下级运营商数量
        example = new UmsMemberExample();
        //合伙人等级为5
        Long partner = 5L;
        example.createCriteria().andMemberLevelIdEqualTo(partner).andParentMemberIdEqualTo(memberId);
        fansCount.setOperatorCount(umsMemberMapper.countByExample(example));

        //查询二级粉丝数量
        UmsMemberFansQueryParam param = new UmsMemberFansQueryParam();
        param.setParentId(memberId);
        param.setFilterType(UmsMemberFansFilterEnum.SECOND_FILTER_FANS.getValue());
        List<UmsMemberFull> secondFans = umsMemberDao.queryFansList(param);
        fansCount.setSecondFansCount(secondFans.size());

        //查询三级粉丝数量,
        param = new UmsMemberFansQueryParam();
        param.setParentId(memberId);
        param.setFilterType(UmsMemberFansFilterEnum.THIRD_FILTER_FANS.getValue());
        List<UmsMemberFull> thirdFans = umsMemberDao.queryFansList(param);
        fansCount.setThridFansCount(thirdFans.size());

        //所有粉丝数量设置
        Integer allFansCount = fansCount.getFirstFansCount() + fansCount.getSecondFansCount() + fansCount.getThridFansCount();
        fansCount.setAllFansCount(allFansCount);

        return fansCount;
    }

    /**
     * 会员佣金已结、未结状态的数量与金额
     * @param memberId
     * @return
     */
    @Override
    public UmsMemberCommissionStatusCount getCommissionStatusCount(Long memberId){
        return umsMemberDao.countStatusCommission(memberId);
    }

    /**
     * 增加到期时间
     * @param param
     */
    @Override
    public void addExpireDate(UmsMemberAddExpireDateParam param){
        //当该会员为代理(等级为2)、合伙人（等级3）时才可以增加到期时间
        UmsMember umsMember = umsMemberMapper.selectByPrimaryKey(param.getMemberId());
        if (StringUtils.isEmpty(umsMember) || (umsMember.getLevelType().intValue() == Constants.MemberLevelType.Member.getValue())) {
            return;
        }
        UmsMemberUpgradeExample upgradeExample = new UmsMemberUpgradeExample();
        upgradeExample.createCriteria().andMemberIdEqualTo(param.getMemberId());
        List<UmsMemberUpgrade> memberUpgradeList = memberUpgradeMapper.selectByExample(upgradeExample);

        if (null != memberUpgradeList && !memberUpgradeList.isEmpty()) {
            UmsMemberUpgrade memberUpgrade = new UmsMemberUpgrade();
            memberUpgrade.setId(memberUpgradeList.get(0).getId());
            // 2 为手动升级
            memberUpgrade.setUpgradeType(UmsMemberUpgrade.UpgradeType.MANUAL.getValue());
            memberUpgrade.setExpiredType(param.getExpireType());
            memberUpgrade.setExpiredDate(addExpireDate(param.getExpireType(),memberUpgradeList.get(0).getExpiredDate()));
            memberUpgradeMapper.updateByPrimaryKeySelective(memberUpgrade);
        }
    }

    /**
     * 到期时间按照expireType增加
     * @param expiredType
     * @param expireDate
     * @return
     */
    private int addExpireDate(Integer expiredType,Integer expireDate){
        Date dateExpireDate;
        if (StringUtils.isEmpty(expireDate)){
            dateExpireDate = new Date();
        }else {
            dateExpireDate = DateTimeHelper.getDateFromEpochTimeInSecond(expireDate);
        }
        Date expired;
        switch (expiredType) {
            case 1:
                expired = DateTimeHelper.addDays(dateExpireDate, 30);
                break;
            case 2:
                expired = DateTimeHelper.addDays(dateExpireDate, 365);
                break;
            case 3:
                expired = DateTimeHelper.getDate(2020, 12, 25);
                break;
            default:
                expired = new Date();
        }
        return DateTimeHelper.getEpochTimeInSecond(expired);
    }

    private void formatMemberList(List<UmsMemberFull> memberFullList) {
        if (!memberFullList.isEmpty()) {
            for (UmsMemberFull member : memberFullList) {
                try {
                    String nickname = StringUtils.isEmpty(member.getNickname()) ? "未授权" : member.getNickname();
                    String parentNickname = StringUtils.isEmpty(member.getParentNickname()) ? "" : member.getParentNickname();
                    member.setNickname(URLDecoder.decode(nickname, "utf-8"));
                    member.setParentNickname(URLDecoder.decode(parentNickname, "utf-8"));
                    String icon = StringUtils.isEmpty(member.getIcon()) ? Constants.DEFAULT_HEADPORTAL : member.getIcon();
                    member.setIcon(icon);

                    OmsOrderExample example=new OmsOrderExample();
                    example.createCriteria().andMemberIdEqualTo(member.getId()).andStatusBetween(1,3);

                    member.setOrderCount(orderMapper.countByExample(example));
                } catch (Exception e) {
                    member.setNickname("");
                    member.setParentNickname("");
                }
            }
        }
    }

    private int getExpireDate(Integer expiredType) {
        Date expired;
        switch (expiredType) {
            case 1:
                expired = DateTimeHelper.addDays(new Date(), 30);
                break;
            case 2:
                expired = DateTimeHelper.addDays(new Date(), 365);
                break;
            case 3:
                expired = DateTimeHelper.getDate(2020, 12, 25);
                break;
            default:
                expired = new Date();
        }
        return DateTimeHelper.getEpochTimeInSecond(expired);
    }


    public void checkDeleteMember(Long memberId) {
        // 检测是否是别人的推荐人
        UmsMemberExample memberExample = new UmsMemberExample();
        memberExample.createCriteria().andParentMemberIdEqualTo(memberId);
        if (umsMemberMapper.countByExample(memberExample) > 0) {
            throw new ServiceException("该用户有粉丝不可删除");
        }

        OmsOrderExample orderExample = new OmsOrderExample();
        orderExample.createCriteria().andMemberIdEqualTo(memberId).andStatusBetween(1, 3);
        if (orderMapper.countByExample(orderExample) > 0) {
            throw new ServiceException("该用户有付款订单不可删除");
        }

    }
}
